﻿using Leap;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Input;
//using System.Windows.Input;




namespace LeapMotionMouse
{
    class MouseListener : Listener
    {
        private long CurrentFrameTime;      // timestamp from the current frame
        private long PreviousFrameTime;     // timestamp from the last frame
        private long TimeDifference;        // difference between timestamps

        public long lastClick { get; set; }
        const int FramePause = 10000;       // time to wait between frames in mircosecond

        Finger PreviousFinger;
        Finger PointerFinger;
        Finger TappingFinger;
        public static int ONE_SECOND = 10000000;
        float? PreviousxScreenIntersect = null;
        float? PreviousyScreenIntersect = null;
        float? CurrentxScreenIntersect = null;
        float? CurrentyScreenIntersect = null;
        private static MouseListener mouseListener;


        private MouseListener() { }

        public static MouseListener getInstance()
        {
            if (mouseListener == null)
            {
                mouseListener = new MouseListener();
            }
            return mouseListener;
        }

        public void setLastClick(int increase)
        {
            lastClick = DateTime.Now.Ticks + increase;
        }

        public override void OnFrame(Controller cntrlr)
        {
            Frame CurrentFrame = cntrlr.Frame();                    // get current frame
            CurrentFrameTime = CurrentFrame.Timestamp;              // extract timestamp
            TimeDifference = CurrentFrameTime - PreviousFrameTime;  // calculate difference

            if (TimeDifference > FramePause)
            {

                if (CurrentFrame.Hands.Count >= 1)
                {
                    moveCursorLeapMotion(cntrlr, CurrentFrame);
                    MouseClick2(CurrentFrame);
                }

                PreviousFrameTime = CurrentFrameTime;
            }
        }

        private void MouseClick2(Frame CurrentFrame)
        {
            if (CurrentFrame.Hands.Count == 1)
            {
                Hand hand = CurrentFrame.Hands[0];
                TappingFinger = hand.Fingers.Frontmost;

                if (hand.Fingers.Count == 2)
                {
                    if (isPointerZdirection(hand.Fingers[0].Direction) && isPointerZdirection(hand.Fingers[1].Direction))
                    {
                        long diff = DateTime.Now.Ticks - lastClick;
                        // 2 segundos
                        if (diff > 10000000)
                        {
                            //Console.Beep();
                            MouseSimulator.ClickLeftMouseButton();
                            lastClick = DateTime.Now.Ticks;
                        }
                    }
                }
            }
        }/*
        private void MouseClick(Frame CurrentFrame)
        {
            if (CurrentFrame.Hands.Count == 2)
            {
                Hand LeftHand = CurrentFrame.Hands.Leftmost;
                Hand RightHand = CurrentFrame.Hands.Rightmost;
                TappingFinger = LeftHand.Fingers.Frontmost;

                if (LeftHand.Fingers.Count == 1 && RightHand.Fingers.Count == 1)
                {
                    if (isPointerZdirection(LeftHand.Fingers[0].Direction))
                    {
                        long diff = DateTime.Now.Ticks - lastClick;
                        // 2 segundos
                        if (diff > 10000000)
                        {
                            MouseSimulator.ClickLeftMouseButton();
                            lastClick = DateTime.Now.Ticks;

                            Console.Beep();
                        }
                    }
                }
            }
        }*/
        private bool isPointerZdirection(Vector vector)
        {
            if (vector.z < -0.7)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        private void moveCursorLeapMotion(Controller cntrlr, Frame CurrentFrame)
        {
            // ...
            PreviousFinger = PointerFinger;

            Hand RightHand = CurrentFrame.Hands.Rightmost;
            // Hand LeftHand = CurrentFrame.Hands.Leftmost;

            PointerFinger = RightHand.Fingers.Frontmost;
            //     TappingFinger = LeftHand.Fingers.Frontmost;

            // Get the closest screen intercepting a ray projecting from the finger
            Leap.Screen screen = cntrlr.LocatedScreens.ClosestScreenHit(PointerFinger);

            if (screen != null && screen.IsValid && PreviousFinger != null)
            {
                // Get the velocity of the finger tip (norm)
                var tipVelocity = Math.Sqrt(PointerFinger.TipVelocity.x * PointerFinger.TipVelocity.x + PointerFinger.TipVelocity.y * PointerFinger.TipVelocity.y);

                if (tipVelocity > 30)
                {
                    PreviousxScreenIntersect = CurrentxScreenIntersect;
                    PreviousyScreenIntersect = CurrentyScreenIntersect;

                    CurrentxScreenIntersect = screen.Intersect(PointerFinger, true).x;
                    CurrentyScreenIntersect = screen.Intersect(PointerFinger, true).y;

                    if (CurrentxScreenIntersect.ToString() != "NaN")
                    {
                        var x = (int)(CurrentxScreenIntersect * screen.WidthPixels);
                        var y = (int)(screen.HeightPixels - (CurrentyScreenIntersect * screen.HeightPixels));
                        //Cursor.Position = new Point(0, 0);
                        //      Cursor c = Cursors.Hand;
                        System.Windows.Forms.Cursor.Position = new System.Drawing.Point(x, y);
                        //   System.Windows.Input.Mouse.SetCursor(c);
                        //  Mouse.Move(x, y, false);  // this set the cursor to this position
                    }

                }
            }
        }

    }
}
